package org.darcy.controller.portal;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.darcy.entity.BizPage;
import org.darcy.entity.SysTemplate;
import org.darcy.framework.annotation.BussinessLog;
import org.darcy.framework.blog.business.enums.TemplateKeyEnum;
import org.darcy.framework.util.FreeMarkerUtil;
import org.darcy.framework.util.ResultUtil;
import org.darcy.service.BizArticleArchivesService;
import org.darcy.service.BizArticleService;
import org.darcy.service.BizPageService;
import org.darcy.service.BizTagsService;
import org.darcy.service.BizTypeService;
import org.darcy.service.SysConfigService;
import org.darcy.service.SysLinkService;
import org.darcy.service.SysTemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * 站点相关的接口类，主要为sitemap和robots的生成
 */
@Controller
public class WebSiteController {
	@Autowired
	private BizArticleService articleService;
	@Autowired
	private BizTypeService typeService;
	@Autowired
	private BizTagsService tagsService;
	@Autowired
	private SysTemplateService templateService;
	@Autowired
	private SysConfigService configService;

	@Autowired
	private BizArticleArchivesService bizArticleArchivesService;

	@Autowired
	private SysLinkService sysLinkService;

	/**
	 * 顶部：1.关于本站
	 */
	@GetMapping("/about")
	@BussinessLog(value = "进入关于页")
	public ModelAndView about() {
		return ResultUtil.view("about");
	}

	/**
	 * 顶部：2.友情链接
	 */
	@GetMapping("/links")
	@BussinessLog(value = "进入友情链接页")
	public ModelAndView links(Model model) {
		model.addAttribute("link", sysLinkService.listAllByGroup());
		return ResultUtil.view("links");
	}

	/**
	 * 顶部：3.留言板
	 */
	@GetMapping("/guestbook")
	@BussinessLog(value = "进入留言板页")
	public ModelAndView guestbook() {
		return ResultUtil.view("guestbook");
	}

	/**
	 * 底部：1.网站地图
	 */
	@GetMapping(value = "/sitemap", produces = "text/html;charset=UTF-8")
	@BussinessLog(value = "查看sitemap")
	public ModelAndView sitemap(ModelMap map) {
		map.put("articleTypeList", typeService.getList(null));
		map.put("articleTagsList", tagsService.getList(null));
		map.put("articleList", articleService.getList(null));
		map.put("config", configService.getConfigs());
		// String data = getSitemap(TemplateKeyEnum.TM_SITEMAP_HTML);
		return ResultUtil.view("sitemap");
	}

	/**
	 * 底部：2.站长推荐
	 */
	@GetMapping("/recommended")
	@BussinessLog(value = "进入站长推荐页")
	public ModelAndView recommended(Model model) {
		model.addAttribute("list", articleService.listRecommended(100));
		return ResultUtil.view("recommended");
	}

	/**
	 * 底部：3.归档目录
	 */
	@GetMapping("/archives")
	@BussinessLog(value = "进入归档目录页")
	public ModelAndView archives(Model model) {
		Map<String, List> map = bizArticleArchivesService.listArchives();
		model.addAttribute("archives", map);
		return ResultUtil.view("archives");
	}

	/**
	 * 底部：4.免责声明
	 */
	@GetMapping("/disclaimer")
	@BussinessLog(value = "进入免责声明页")
	public ModelAndView disclaimer() {
		return ResultUtil.view("disclaimer");
	}

	@GetMapping(value = "/sitemap.xml", produces = "application/xml;charset=UTF-8")
	@BussinessLog(value = "查看sitemap.xml")
	@ResponseBody
	public String sitemapXml() {
		return getSitemap(TemplateKeyEnum.TM_SITEMAP_XML);
	}

	@GetMapping(value = "/sitemap.txt", produces = { "text/plain" })
	@BussinessLog(value = "查看sitemap.txt")
	@ResponseBody
	public String sitemapTxt() {
		return getSitemap(TemplateKeyEnum.TM_SITEMAP_TXT);
	}

	@GetMapping(value = "/robots.txt", produces = { "text/plain" })
	@BussinessLog(value = "查看robots")
	@ResponseBody
	public String robots() {
		SysTemplate template = templateService.getTemplate(TemplateKeyEnum.TM_ROBOTS);
		Map<String, Object> map = new HashMap<>();
		map.put("config", configService.getConfigs());
		return FreeMarkerUtil.template2String(template.getRefValue(), map, true);
	}

	private String getSitemap(TemplateKeyEnum key) {
		SysTemplate template = templateService.getTemplate(key);
		Map<String, Object> map = new HashMap<>();
		map.put("articleTypeList", typeService.getList(null));
		map.put("articleTagsList", tagsService.getList(null));
		map.put("articleList", articleService.getList(null));
		map.put("config", configService.getConfigs());
		return FreeMarkerUtil.template2String(template.getRefValue(), map, true);
	}

	@Autowired
	private BizPageService bizPageService;

	// 自定义页面
	@GetMapping(value = "/{filename}.xml", produces = { "application/xml" })
	@ResponseBody
	public String xml(@PathVariable("filename") String filename) {
		return this.getContent(filename + ".xml");
	}

	@GetMapping(value = "/{filename}.txt", produces = { "text/plain" })
	@ResponseBody
	public String txt(@PathVariable("filename") String filename) {
		return this.getContent(filename + ".txt");
	}

	@GetMapping(value = "/.well-known/{url}/{filename}.txt", produces = { "text/plain" })
	@ResponseBody
	public String multiPath(@PathVariable("url") String url, @PathVariable("filename") String filename) {
		return this.getContent(".well-known/" + url + "/" + filename + ".txt");
	}

	@GetMapping(value = "/{filename}.html", produces = { "text/html" })
	@ResponseBody
	public String html(@PathVariable("filename") String filename) {
		return this.getContent(filename + ".html");
	}

	// 获取自定义页面内容
	private String getContent(String url) {
		BizPage page = bizPageService.getByUrl(url);
		return null == page ? "" : page.getContent();
	}

	/**
	 * 403
	 */
	@GetMapping(value = "/error/403")
	public ModelAndView error403(ModelMap map) {
		return ResultUtil.view("error/403");
	}

	/**
	 * 404
	 */
	@GetMapping(value = "/error/404")
	public ModelAndView error404(ModelMap map) {
		return ResultUtil.view("error/404");
	}

	/**
	 * 500
	 */
	@GetMapping(value = "/error/500")
	public ModelAndView error500(ModelMap map) {
		return ResultUtil.view("error/500");
	}

}
